package org.example;

import java.awt.*;
import java.util.ArrayList;
import java.util.Random;

public class Buildings {
    private ArrayList<Point> buildings;
    private int gridWidth;
    private int gridHeight;
    private int tileSize;
    private Random random = new Random();

    public Buildings(int gridWidth, int gridHeight, int tileSize) {
        this.gridWidth = gridWidth;
        this.gridHeight = gridHeight;
        this.tileSize = tileSize;
        buildings = new ArrayList<>();
    }

    //固定障碍
    public void generateMap1() {
        buildings.clear();
        // 添加边框障碍
        for (int x = 0; x < gridWidth; x++) {
            buildings.add(new Point(x, 0, new Color(100, 100, 200)));
            buildings.add(new Point(x, gridHeight - 1, new Color(100, 100, 200)));
        }
        for (int y = 1; y < gridHeight - 1; y++) {
            buildings.add(new Point(0, y, new Color(100, 100, 200)));
            buildings.add(new Point(gridWidth - 1, y, new Color(100, 100, 200)));
        }
        // 添加内部障碍
        for (int i = 1; i < 5; i++) {
            int x = i * gridWidth / 6;
            int y = i * gridHeight / 6;
            // 水平障碍
            for (int j = 0; j < 8; j++) {
                buildings.add(new Point(x + j, y, new Color(120, 120, 220)));
            }
            // 垂直障碍
            for (int j = 0; j < 6; j++) {
                buildings.add(new Point(gridWidth - x, gridHeight - y - j, new Color(120, 120, 220)));
            }
        }
    }
    //迷宫
    public void generateMap2() {
        buildings.clear();
        Random random = new Random();

        // 1. 绘制边界墙（外围封闭）
        for (int x = 0; x < gridWidth; x++) {
            buildings.add(new Point(x, 0, new Color(100, 100, 200))); // 上边界
            buildings.add(new Point(x, gridHeight - 1, new Color(100, 100, 200))); // 下边界
        }
        for (int y = 1; y < gridHeight - 1; y++) {
            buildings.add(new Point(0, y, new Color(100, 100, 200))); // 左边界
            buildings.add(new Point(gridWidth - 1, y, new Color(100, 100, 200))); // 右边界
        }

        // 2. 绘制横向主隔断（将地图分为上下区域，留随机通道）
        int horizontalDividerY = gridHeight / 2; // 中间横向隔断
        for (int x = 0; x < gridWidth; x++) {
            // 每隔5格留一个通道（随机偏移避免规律）
            if (x % 5 != random.nextInt(3)) { // 随机跳过部分格子作为通道
                buildings.add(new Point(x, horizontalDividerY, new Color(120, 120, 220)));
            }
        }

        // 3. 绘制纵向主隔断（将地图分为左右区域，留随机通道）
        int verticalDividerX = gridWidth / 2; // 中间纵向隔断
        for (int y = 0; y < gridHeight; y++) {
            // 每隔5格留一个通道（与横向通道错开）
            if (y % 5 != (random.nextInt(3) + 2)) { // 偏移通道位置，避免十字通道
                buildings.add(new Point(verticalDividerX, y, new Color(120, 120, 220)));
            }
        }

        // 4. 四个象限内添加随机子隔断（增加迷宫复杂度）
        // 左上象限 (0~15, 0~15)
        addRandomSubDividers(1, 2, verticalDividerX - 1, horizontalDividerY - 1, random);
        // 右上象限 (16~29, 0~15)
        addRandomSubDividers(verticalDividerX + 1, 1, gridWidth - 2, horizontalDividerY - 1, random);
        // 左下象限 (0~15, 16~29)
        addRandomSubDividers(1, horizontalDividerY + 1, verticalDividerX - 1, gridHeight - 3, random);
        // 右下象限 (16~29, 16~29)
        addRandomSubDividers(verticalDividerX + 1, horizontalDividerY + 1, gridWidth - 2, gridHeight - 2, random);
    }

    /**
     * 在指定区域内添加随机子隔断（辅助方法）
     * @param startX 区域起始X
     * @param startY 区域起始Y
     * @param endX 区域结束X
     * @param endY 区域结束Y
     * @param random 随机数生成器
     */
    private void addRandomSubDividers(int startX, int startY, int endX, int endY, Random random) {
        // 每个区域生成6-10个随机隔断
        int dividerCount = random.nextInt(5) + 6;

        for (int i = 0; i < dividerCount; i++) {
            // 随机选择横向或纵向隔断
            boolean isHorizontal = random.nextBoolean();

            if (isHorizontal) {
                // 横向隔断：固定Y，随机X范围
                int y = random.nextInt(endY - startY) + startY;
                int xStart = random.nextInt(endX - startX - 5) + startX; // 起始X
                int length = random.nextInt(4) + 3; // 长度3-6格

                // 留一个缺口（避免完全封死）
                int gapPos = random.nextInt(length); // 缺口位置

                for (int x = 0; x < length; x++) {
                    int currentX = xStart + x;
                    // 跳过缺口位置，且不超出区域范围
                    if (x != gapPos && currentX < endX) {
                        buildings.add(new Point(currentX, y, new Color(90, 90, 210)));
                    }
                }
            } else {
                // 纵向隔断：固定X，随机Y范围
                int x = random.nextInt(endX - startX) + startX;
                int yStart = random.nextInt(endY - startY - 5) + startY; // 起始Y
                int length = random.nextInt(4) + 3; // 长度3-6格

                // 留一个缺口
                int gapPos = random.nextInt(length);

                for (int y = 0; y < length; y++) {
                    int currentY = yStart + y;
                    // 跳过缺口位置，且不超出区域范围
                    if (y != gapPos && currentY < endY) {
                        buildings.add(new Point(x, currentY, new Color(90, 90, 210)));
                    }
                }
            }
        }
    }
    //乱石
    public void generateMap3() {
        buildings.clear();
        // 添加边框障碍
        for (int x = 0; x < gridWidth; x++) {
            buildings.add(new Point(x, 0, new Color(100, 100, 200)));
            buildings.add(new Point(x, gridHeight - 1, new Color(100, 100, 200)));
        }
        for (int y = 1; y < gridHeight - 1; y++) {
            buildings.add(new Point(0, y, new Color(100, 100, 200)));
            buildings.add(new Point(gridWidth - 1, y, new Color(100, 100, 200)));
        }

        // 要生成的建筑块数量
        int blockCount = 9;

        // 生成随机建筑块
        for (int i = 0; i < blockCount; i++) {
            // 随机位置（避开边界和蛇的起始位置）
            int x, y;
            x = random.nextInt(gridWidth - 1) + 2;
            y = random.nextInt(gridHeight - 2) + 3;


            // 随机决定建筑类型：单点、直线或矩形
            int structureType = random.nextInt(3);

            if (structureType == 0) {
                // 单点建筑
                buildings.add(new Point(x, y, getRandomBuildingColor()));
            } else if (structureType == 1) {
                // 直线建筑
                int length = random.nextInt(4) + 2; // 2-5个单位长度
                boolean isHorizontal = random.nextBoolean();

                for (int j = 0; j < length; j++) {
                    int bx = isHorizontal ? x + j : x;
                    int by = isHorizontal ? y : y + j;

                    // 确保不超出边界
                    if (bx < gridWidth - 1 && by < gridHeight - 1) {
                        buildings.add(new Point(bx, by, getRandomBuildingColor()));
                    }
                }
            } else {
                // 矩形建筑
                int width = random.nextInt(3) + 2;  // 2-4个单位宽
                int height = random.nextInt(3) + 2; // 2-4个单位高

                for (int dx = 0; dx < width; dx++) {
                    for (int dy = 0; dy < height; dy++) {
                        int bx = x + dx;
                        int by = y + dy;

                        // 确保不超出边界
                        if (bx < gridWidth - 1 && by < gridHeight - 1) {
                            buildings.add(new Point(bx, by, getRandomBuildingColor()));
                        }
                    }
                }
            }
        }
    }
    //宝藏
    public void generateMap4() {
        buildings.clear();
        Random random = new Random();
        int center = 15; // 30×30网格中心坐标（0-29）
        int centerSize = 1; // 5×5中心空白区（坐标13-17, 13-17）

        // 蛇的起始安全区（避开生成障碍）
        // 左上起始区：x=2-6, y=1-4
        // 左下起始区：x=2-6, y=25-28
        int[][] safeZones = {
                {2, 1, 6, 4},   // 左上安全区
                {2, 25, 6, 28}  // 左下安全区
        };

        // 1. 外围边界墙（使用蓝色系深色调）
        Color borderColor = new Color(80, 80, 180); // 深色调边界
        for (int x = 0; x < gridWidth; x++) {
            buildings.add(new Point(x, 0, borderColor));
            buildings.add(new Point(x, gridHeight - 1, borderColor));
        }
        for (int y = 1; y < gridHeight - 1; y++) {
            buildings.add(new Point(0, y, borderColor));
            buildings.add(new Point(gridWidth - 1, y, borderColor));
        }

        // 2. 中心保护墙（围绕5×5空白区，蓝色系中色调）
        int protectRange = centerSize + 2; // 保护墙距离中心的范围（格）
        int entranceCount = 0; // 记录入口数量，确保至少2个
        for (int x = center - protectRange; x <= center + protectRange; x++) {
            for (int y = center - protectRange; y <= center + protectRange; y++) {
                // 保护墙外层（环形）
                boolean isOuterWall = (x == center - protectRange || x == center + protectRange ||
                        y == center - protectRange || y == center + protectRange);
                // 排除5×5中心空白区（13-17,13-17）
                boolean isInCenter = (x >= center - 2 && x <= center + 2 &&
                        y >= center - 2 && y <= center + 2);

                if (isOuterWall && !isInCenter) {
                    // 优先在蛇起始区方向（左上、左下）留入口
                    boolean isNearStart = (y < 10 || y > 20);
                    if (entranceCount < 2 && (isNearStart || random.nextInt(10) < 3)) {
                        entranceCount++; // 留入口（不生成墙）
                    } else {
                        // 使用统一的蓝色系建筑色
                        buildings.add(new Point(x, y, getRandomBuildingColor()));
                    }
                }
            }
        }

        // 3. 外围迷宫障碍（蓝色系，控制密度，避开蛇起始区）
        int maxObstacles = 60; // 障碍数量适中，确保路径连通
        for (int i = 0; i < maxObstacles; i++) {
            // 随机位置（避开边界2格，避免贴边堵塞）
            int x = random.nextInt(gridWidth - 4) + 2;
            int y = random.nextInt(gridHeight - 4) + 2;

            // 检查是否在蛇的安全区（必须避开）
            boolean inSafeZone = false;
            for (int[] zone : safeZones) {
                int zx1 = zone[0], zy1 = zone[1], zx2 = zone[2], zy2 = zone[3];
                if (x >= zx1 && x <= zx2 && y >= zy1 && y <= zy2) {
                    inSafeZone = true;
                    break;
                }
            }

            // 排除中心区和保护墙区
            boolean isInCenter = (x >= center - 2 && x <= center + 2 &&
                    y >= center - 2 && y <= center + 2);
            boolean isInProtect = (x >= center - protectRange && x <= center + protectRange &&
                    y >= center - protectRange && y <= center + protectRange);

            if (!inSafeZone && !isInCenter && !isInProtect) {
                // 生成短障碍段（2-4格），避免长障碍封死路径
                boolean isHorizontal = random.nextBoolean();
                int length = random.nextInt(3) + 2; // 长度2-4格

                if (isHorizontal) {
                    for (int j = 0; j < length; j++) {
                        int currX = x + j;
                        // 确保不超出范围且不在安全区
                        if (currX < gridWidth - 3 && !inSafeZone) {
                            buildings.add(new Point(currX, y, getRandomBuildingColor()));
                        }
                    }
                } else {
                    for (int j = 0; j < length; j++) {
                        int currY = y + j;
                        if (currY < gridHeight - 3 && !inSafeZone) {
                            buildings.add(new Point(x, currY, getRandomBuildingColor()));
                        }
                    }
                }
            }
        }
    }
   /* public void generateMap4() {
        buildings.clear();
        // 添加边框障碍

        for (int y = 1; y < gridHeight - 1; y++) {
            buildings.add(new Point(0, y, new Color(190, 190, 190, 255)));
            buildings.add(new Point(gridWidth - 1, y, new Color(114, 103, 45)));
            //添加砖石形状障碍物
            for (int x = 1; x < gridWidth - 1; x++) {
                if (x % 20 == 0) {
                    buildings.add(new Point(x, y, new Color(100, 100, 200)));
                }
            }
        }
    }*/

    // 辅助：判断是否在蛇的安全区（用于其他逻辑复用）
    private boolean isInSafeZone(int x, int y, int[][] safeZones) {
        for (int[] zone : safeZones) {
            int zx1 = zone[0], zy1 = zone[1], zx2 = zone[2], zy2 = zone[3];
            if (x >= zx1 && x <= zx2 && y >= zy1 && y <= zy2) {
                return true;
            }
        }
        return false;
    }

    // 检查是否靠近蛇的起始位置

    // 检查是否靠近现有建筑（避免建筑过于密集）
    private boolean isNearExistingBuilding(int x, int y) {
        int minDistance = 1; // 与现有建筑的最小距离
        for (Point building : buildings) {
            int dist = Math.abs(x - building.getGridX()) + Math.abs(y - building.getGridY());
            if (dist <= minDistance) {
                return true;
            }
        }
        return false;
    }

    // 获取随机建筑颜色
    private Color getRandomBuildingColor() {
        // 从几种蓝色调中随机选择
        Color[] colors = {
                new Color(42, 114, 38),
                new Color(120, 120, 220),
                new Color(150, 45, 45),
                new Color(90, 90, 210)
        };

        return colors[random.nextInt(colors.length)];
    }

    public boolean checkCollision(org.example.Point point) {
        for (org.example.Point building : buildings) {
            if (building.equals(point)) {
                return true;
            }
        }
        return false;
    }

    public void draw(Graphics2D g) {
        for (org.example.Point building : buildings) {
            g.setColor(building.getColor());

            int pixelX = building.getGridX() * tileSize;
            int pixelY = building.getGridY() * tileSize;

            g.fillRect(pixelX, pixelY, tileSize, tileSize);

            // 添加纹理
            g.setColor(new Color(255, 255, 255, 50));
            g.drawRect(pixelX + 2, pixelY + 2, tileSize - 4, tileSize - 4);
            g.drawLine(pixelX + 4, pixelY + 4, pixelX + tileSize - 4, pixelY + tileSize - 4);
            g.drawLine(pixelX + tileSize - 4, pixelY + 4, pixelX + 4, pixelY + tileSize - 4);
        }
    }

    public ArrayList<org.example.Point> getBuildings() {
        return buildings;
    }
}